from PreRec.UCF.Trainer import Trainer
from tqdm import tqdm
from typing import Dict, List


class Recommender:
    def __init__(self, hyper_params):
        self.hyper_params = hyper_params

        self.trainer = Trainer(hyper_params)
        self.user_cnt = self.trainer.file_loader.reader_cnt
        self.item_cnt = self.trainer.file_loader.book_cnt

        self.W: Dict[int, Dict[int, float]] = self.trainer.W
        self.user_book_list: Dict[int, List[int]
                                  ] = self.trainer.interaction_list

    def recommend(self, max_cnt=500) -> Dict[int, List[int]]:
        print('UCF: Start User-based CF recommendation...')
        result: Dict[int, List[int]] = {}

        for user in tqdm(range(self.user_cnt)):
            result[user] = []

            if user not in self.W or len(self.W[user]) == 0:
                continue

            similar_user_list = list(self.W[user].items())
            similar_user_list = sorted(
                similar_user_list, key=lambda x: x[1], reverse=True)

            recommend_books: set = set()
            for u, _ in similar_user_list:
                flag = False
                for b in self.user_book_list[u]:
                    recommend_books.add(b)

                    if recommend_books.__len__() >= max_cnt:
                        flag = True
                        break

                if flag:
                    break

            result[user].extend(list(recommend_books))

        print('UCF: Finished User-based CF recommendation.')
        return result


if __name__ == '__main__':
    hyper_params = {
        'dataset_path': '../datasets/lib.txt'
    }

    recommender = Recommender(hyper_params)
    result = recommender.recommend(max_cnt=500)

    print(result)
